package pluginMain;

import java.util.HashMap;
import java.util.List;

import org.bukkit.ChatColor;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;

import pluginMain.Effect.EffectType;
import skill.Skill;
import skill.SkillBase.SkillType;

public class EffectsParser {
	private LivingEntity damager, entity;
	private HashMap<Effect, String> effect = new HashMap<Effect, String>();
	private double globalCritical = 1;
	private EffectCotainer ec;

	public void addEffect(String effectName, String formatedLevel) {
		Effect ef = Lore.ef.getEffectByName(effectName);
		if (ef.getEffect() == EffectType.CriticalMultiply) {
			globalCritical += ef.getLevelByName(formatedLevel);
		} else {
			effect.put(Lore.ef.getEffectByName(effectName), formatedLevel);
		}
	}

	public void addBaseEffect(String effectName, int min, int max) {
		Effect ef = Lore.ef.getEffectByName(effectName);
		ef.setValue(max, min);
		effect.put(ef, "N");
	}

	public void clear() {
		effect = new HashMap<Effect, String>();
		globalCritical = 0;
	}

	public void doEffects(EntityDamageByEntityEvent e) {
		damager = Lore.getDamager(e);
		entity = Lore.getEntity(e);
		ec = new EffectCotainer(e, e.getFinalDamage());
		final double finalDamage = e.getFinalDamage();

		// start effect apply
		try {
			for (Effect le : effect.keySet()) {
				if (le.getEffect() == EffectType.CriticalDamage) {
					if (getRandom((int) globalCritical)) {
						double criticalDamage = le.getValue();
						ec.addDamage(criticalDamage);
						damager.sendMessage("Critical! " + ChatColor.RED + Lore.r2(criticalDamage) + " Damage");
					}
					continue;
				} else if (le.getEffect() == EffectType.DefaultDamage) {
					ec.addDamage(le.getValue());
					continue;
				} else if (le.getEffect() == EffectType.DefaultAmmor) {
					ec.addDamage(-le.getValue());
					continue;
				}

				int stage = le.getLevelByName(effect.get(le));
				boolean random = getRandom(stage);

				switch (le.getEffect()) {
				case Harden:
					if (finalDamage <= le.getLevelByName(effect.get(le))) {
						e.setCancelled(true);
						return;
					}
					break;
				case LifeSteal:
					double max = damager.getMaxHealth();
					double steal = ec.getDamage() * (stage / 100d);
					double heal = damager.getHealth() + steal;
					damager.setHealth(max < heal ? max : heal);
					if (damager instanceof Player) {
						((Player) damager).sendMessage(le.getName() + " Steal "
								+ ChatColor.GREEN + Lore.r2(steal) + " Health");
					}
					break;
				case Freeze:
					if (random) {
						ec.addPotionEffect(EffectCotainer.VICTIM,
								new PotionEffect(PotionEffectType.SLOW_DIGGING, 10, 1));
						ec.addPotionEffect(EffectCotainer.VICTIM, new PotionEffect(PotionEffectType.SLOW, 10, 1));
						if (damager instanceof Player)
							((Player) damager).sendMessage("Freezed!");
					}
					break;
				case Buff:
					if (finalDamage > 1.0f) {
						if (random) {

						}
					}
					break;
				case Poison:
					if (random)
						ec.addPotionEffect(EffectCotainer.VICTIM, new PotionEffect(PotionEffectType.POISON, 10, 1));
					break;
				case AntiPoison:
					if (random)
						ec.removePotionEffect(true, PotionEffectType.POISON);
					break;
				case Burn:
					if (random)
						entity.setFireTicks(entity.getFireTicks() + 80);
					break;
				case AntiFire:
					if (random)
						entity.setFireTicks(0);
					break;
				case AttackTwice:
					if (finalDamage > 1.0f)
						entity.setHealth(entity.getHealth() - e.getDamage() * stage / 100d);
					break;
				case ReserveAttact:
					damager.damage(finalDamage);
					break;
				case IgnoreAmmor:
					// Ignore ammor damage
					// move to ec
					// entity.setHealth(entity.getHealth() - e.getDamage() *
					// stage / 100d);
					// cost Normal damage
					ec.addPureDamage(ec.getDamage() * stage / 100d);
					ec.addDamage(-ec.getDamage() * stage / 100d);
					// add Pure Damage
					break;
				case Dodge:
					// Cancel all damage
					if (random) {
						e.setCancelled(true);
						return;
					}
					break;
				case Stand:
					break;
				case Sacrifice:
					// Damage the damagaer.
					damager.setHealth(damager.getHealth() - stage);
					break;
				case Therapy:
					e.setCancelled(true);
					entity.setHealth(entity.getHealth() + stage);
					return;
				case Withered:
					if (random)
						entity.addPotionEffect(new PotionEffect(PotionEffectType.WITHER, 10, 1));
					break;
				case SPSkill:
					if (damager instanceof Player) {
						double percentMultiply = 0.0d;
						Player damagerPlayer = (Player) damager;
						List<Skill> skills = Lore.sm.getPlayerSkills(damagerPlayer).getSkillByType(SkillType.Skill);
						for (Skill sk : skills) {
							percentMultiply += sk.getLevel() * stage / 100d;
						}
						percentMultiply /= skills.size();
						ec.addDamage(percentMultiply);
					}
					break;
				case SPHeavn:
					if (damager instanceof Player) {
						double percentMultiply = 0.0d;
						Player damagerPlayer = (Player) damager;
						List<Skill> skills = Lore.sm.getPlayerSkills(damagerPlayer)
								.getSkillByType(SkillType.HeavenWeapon);
						for (Skill sk : skills) {
							percentMultiply += sk.getLevel() * stage / 100d;
						}
						percentMultiply /= skills.size();
						ec.addDamage(percentMultiply);
					}
					break;
				case SPLight:
					if (damager instanceof Player) {
						double percentMultiply = 0.0d;
						Player damagerPlayer = (Player) damager;
						List<Skill> skills = Lore.sm.getPlayerSkills(damagerPlayer)
								.getSkillByType(SkillType.LightWeapon);
						for (Skill sk : skills) {
							percentMultiply += sk.getLevel() * stage / 100d;
						}
						percentMultiply /= skills.size();
						ec.addDamage(percentMultiply);
					}
					break;
				case SPRemote:
					if (damager instanceof Player) {
						double percentMultiply = 0.0d;
						Player damagerPlayer = (Player) damager;
						List<Skill> skills = Lore.sm.getPlayerSkills(damagerPlayer)
								.getSkillByType(SkillType.RemoteWeapon);
						for (Skill sk : skills) {
							percentMultiply += sk.getLevel() * stage / 100d;
						}
						percentMultiply /= skills.size();
						ec.addDamage(percentMultiply);
					}
					break;
				default:
					break;
				}
			}
		} catch (Exception err) {

			err.printStackTrace();
		}
		// complate effect apply
		ec.doFianlDamage();
		// now we apply damage into victim player
	}

	public double getFinalDamage() {
		return ec.getPureDamage() + ec.getDamage();
	}

	public boolean getRandom(int percent) {
		return percent >= (int) (Math.random() * 100d);
	}
}
